package app.itgungnir.compose.wan.utils

import androidx.datastore.core.CorruptionException
import androidx.datastore.core.DataStore
import androidx.datastore.core.Serializer
import androidx.datastore.dataStore
import app.itgungnir.compose.wan.WanApp
import app.itgungnir.compose.wan.WanDataStore
import com.google.protobuf.InvalidProtocolBufferException
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import java.io.InputStream
import java.io.OutputStream
import java.io.Serializable

val WanApp.dataStore: DataStore<WanDataStore> by dataStore(
    fileName = "wan_data_store.pb",
    serializer = WanDataStoreSerializer
)

@Suppress("BlockingMethodInNonBlockingContext")
private object WanDataStoreSerializer : Serializer<WanDataStore> {
    override val defaultValue: WanDataStore = WanDataStore.getDefaultInstance()
    override suspend fun writeTo(t: WanDataStore, output: OutputStream) = t.writeTo(output)
    override suspend fun readFrom(input: InputStream): WanDataStore = try {
        WanDataStore.parseFrom(input)
    } catch (e: InvalidProtocolBufferException) {
        throw CorruptionException("Cannot read proto: $e")
    }
}

object LocalDataStore {
    var localData: WanDataStore = WanDataStore.getDefaultInstance()
        private set

    suspend fun observeLocalData() {
        WanApp.instance.dataStore.data.catch {
            emit(WanDataStore.getDefaultInstance())
        }.collect {
            localData = it
        }
    }

    suspend fun updateLocalData(block: (WanDataStore.Builder) -> Unit) {
        WanApp.instance.dataStore.updateData {
            it.toBuilder().apply {
                block.invoke(this)
            }.build()
        }
    }

    suspend fun clearAllLocalData() {
        this.updateLocalData {
            it.clearHasLaunched()
            it.clearCoinInfo()
            it.clearUserInfo()
            it.clearWanAndroidCookies()
            it.clearHasLogin()
            it.clearDarkModeEnabled()
            it.clearUseNonPictureMode()
            it.darkModeExtendSystem = true
            it.showHotArticles = true
            it.fontTypographyIndex = 0
            it.themePaletteIndex = 0
        }
    }
}

data class UserBaseInfo(
    val id: Long = 0L,
    val nickname: String? = null,
    val publicName: String? = null,
    val username: String? = null,
    val collectIds: List<Long>? = null
) : Serializable

data class UserCoinInfo(
    val coinCount: Long = 0L,
    val level: Int = 0,
    val rank: String? = null
) : Serializable
